/* === LICENSE INFO ===
 * This source file is subject to the GPLv3 license that is bundled with this
 * package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl.txt
 * === end of LICENSE INFO === */

/*==============================================================================
  File Name   : GLogDefinition.hpp
  Description : Contains various definitions for GLog module.

  Created on  : 2010-11-27
  Updated on  : 2011-01-30
  Updated by  : Lee Shiou Ming

  Cautions    : (important notes)
  ============================================================================*/

#ifndef GLOGDEFINITION_HPP_
#define GLOGDEFINITION_HPP_

#include <iostream>
#include <string>
#include <vector>


/**
 * @brief All gUtil modules will be wrapped within gUtil namespace.
 */
namespace gUtil
{
/**
 * @brief Namespace for GLog module.
 */
namespace GLog
{
    typedef std::string::value_type LogCharType;
    const static unsigned int LOG_CHAR_SIZE = sizeof(LogCharType);

    //=== Utility
    /**
     * @brief TODO: To be refactor, do not use it outside class LogConfig!
     */
    template<typename EnumType, typename EnumMappedValueType>
    struct EnumValueMap
    {
        EnumType enumValue;
        EnumMappedValueType mappedValue;
    };

    /**
     * @brief TODO: To be refactor, do not use it outside class LogConfig!
     */
    template<typename EnumMappedValueType, typename EnumValueMapping>
    int getEnumValue(
            const EnumMappedValueType _value,
            const std::vector<EnumValueMapping>& _enumValueMapTable)
    {
        int result = -1;

        for (unsigned int i = 0; i < _enumValueMapTable.size(); ++i)
        {
            const EnumValueMapping& valueMap = _enumValueMapTable[i];
            if (valueMap.mappedValue == _value)
            {
                result = valueMap.enumValue;
                break;
            }
        }

        return result;
    };
    //=== end of utility


    //=== Log level definition
    /**
     * @brief Log severity levels, higher level will have more details.
     *
     * These levels are compatible with syslog protocol (RFC3164). Must ensure
     * that this enum is in-sync with array LOG_LEVEL_VALUE_MAP_TABLE.
     */
    enum LogLevel
    {
        LEVEL_EMERGENCY = 0,
        LEVEL_ALERT,
        LEVEL_CRITICAL,
        LEVEL_ERROR,
        LEVEL_WARNING,
        LEVEL_NOTICE,
        LEVEL_INFO,
        LEVEL_DEBUG
    };

    /**
     * @brief Mapping values related to each log level.
     */
    typedef EnumValueMap<LogLevel, std::string> LogLevelValueMap;

    /**
     * @brief Table that lists the mappings of log level values.
     */
    const std::vector<LogLevelValueMap> LOG_LEVEL_VALUE_MAP_TABLE =
    {
        { LEVEL_EMERGENCY, "EMERGENCY" },
        { LEVEL_ALERT,     "ALERT" },
        { LEVEL_CRITICAL,  "CRITICAL" },
        { LEVEL_ERROR,     "ERROR" },
        { LEVEL_WARNING,   "WARNING" },
        { LEVEL_NOTICE,    "NOTICE" },
        { LEVEL_INFO,      "INFO" },
        { LEVEL_DEBUG,     "DEBUG" }
    };
    //=== end of log level definition

    //=== Log output type definition
    /**
     * @brief Log output types which are currently supported by GLog module.
     *
     * Must ensure that this enum is in-sync with array LOG_OUTPUT_TYPE_VALUE_MAP_TABLE.
     */
    enum LogOutputType
    {
        OUTPUT_SCREEN = 0,
        OUTPUT_FILE
    };

    /**
     * @brief Mapping values related to each log output type.
     */
    typedef EnumValueMap<LogOutputType, std::string> LogOutputTypeValueMap;

    /**
     * @brief Table that lists the mappings of log output type values.
     */
    const std::vector<LogOutputTypeValueMap> LOG_OUTPUT_TYPE_VALUE_MAP_TABLE =
    {
        { OUTPUT_SCREEN, "SCREEN" },
        { OUTPUT_FILE,   "FILE" }
    };
    //=== end of log output type definition

    //=== Log rotation interval definition
    /**
     * @brief Time interval.
     *
     * Must ensure that this enum is in-sync with TIME_INTERVAL_VALUE_MAP_TABLE.
     */
    enum TimeInterval
    {
        /**
         * Interval value is zero (or no interval).
         */
        TIME_INTERVAL_NONE = 0,

        /**
         * Threshold: 10:00, 11:00, 12:00, and so on.
         */
        TIME_INTERVAL_HOURLY,

        /**
         * Threshold: Everyday at time 00:00.
         */
        TIME_INTERVAL_DAILY,

        /**
         * Threshold: First day of each month at time 00:00.
         */
        TIME_INTERVAL_MONTHLY
    };

    /**
     * @brief Mapping values related to each time interval.
     */
    typedef EnumValueMap<TimeInterval, std::string> TimeIntervalValueMap;

    /**
     * @brief Table that lists the mappings of time interval values.
     */
    const std::vector<TimeIntervalValueMap> TIME_INTERVAL_VALUE_MAP_TABLE =
    {
        { TIME_INTERVAL_HOURLY,  "TIME_INTERVAL_HOURLY" },
        { TIME_INTERVAL_DAILY,   "TIME_INTERVAL_DAILY" },
        { TIME_INTERVAL_MONTHLY, "TIME_INTERVAL_MONTHLY" }
    };
    //=== end of log rotation interval definition

    /**
     * @brief Configuration file format.
     *
     * Common formats including INI and JSON, but we only support XML for now.
     */
    enum ConfigFileFormat
    {
        CONFIG_FILE_UNSUPPORTED = 0,
        CONFIG_FILE_XML
    };

}  /* end of namespace GLog */
}  /* end of namespace gUtil */

#endif  /* GLOGDEFINITION_HPP_ */
